//设置相关的源码


#include <WiFi.h>
#include <DNSServer.h>
#include <WebServer.h>
#include <ESPmDNS.h>                  //用于设备域名 MDNS.begin("esp32")
#include <esp_wifi.h>                 //用于esp_wifi_restore() 删除保存的wifi信息
#include <Update.h>                   // 引用相关库
const char* APset_SSID = "ESP32SET";  //设置AP热点名称
String bafaUID = "";                  //暂时存储巴法云私钥
String xinzhiUID = "";                //暂时存储心知天气私钥
String xinzhiCity = "";               //暂时存储心知天气城市
String bafaTOPIC = "";
String bafaNAME = "";
String Quotemod = "";
int quotemod = 0;
//#include "pictures.h"  //
extern void drawScale(String, int, int, int, int, float, float, bool opposition);
extern void nextPage(int, int);
extern void centerx(char* text, int y, int mod, int x0, int dx, char* MOD);
extern void centerx(const char* text, int y, int mod, int x0, int dx, char* MOD);
extern void centerx(String& text1, int y, int mod, int x0, int dx, char* MOD);
extern bool tapcheck(int);
extern int espsleep(int);
String picout = "";
const int baudRate = 115200;  //设置波特率
const byte DNS_PORT = 53;     //设置DNS端口号
const int webPort = 80;       //设置Web端口号
const int resetPin = 0;       //设置重置按键引脚,用于删除WiFi信息

const char* AP_SSID = "ESP32";      //设置AP热点名称
const char* AP_PASS = "123456789";  //设置AP热点密码
const char* HOST_NAME = "MY_ESP";   //设置设备名
String scanNetworksID = "";         //用于储存扫描到的WiFi ID
int connectTimeOut_s = 5;           //WiFi连接超时时间，单位秒
IPAddress apIP(192, 168, 4, 1);     //设置AP的IP地址
String wifi_ssid = "";              //暂时存储wifi账号密码
String wifi_pass = "";              //暂时存储wifi账号密码
String wifi_ssid2 = "";             //暂时存储wifi账号密码
String wifi_pass2 = "";             //暂时存储wifi账号密码
//定义根目录首页网页HTML源代码
#define ROOT_HTML "<!DOCTYPE html><html><head><title>WIFI Config by dht</title><meta name=\"viewport\" http-equiv=\"Content-Type\" content=\"width=device-width, initial-scale=1,test/html;charset=utf-8\"></head><style type=\"text/css\">.input{display: block; margin-top: 10px;}.input span{width: 100px; float: left; float: left; height: 36px; line-height: 36px;}.input input{height: 30px;width: 200px;}.btn{width: 120px; height: 35px; background-color: #000000; border:0px; color:#ffffff; margin-top:15px; margin-left:100px;}</style><body><form method=\"POST\" action=\"configwifi\"><label class=\"input\"><span>WiFi名1</span><input type=\"text\" name=\"ssid\" value=\"\"></label><label class=\"input\"><span>WiFi密码1</span><input type=\"text\"  name=\"pass\"></label><label class=\"input\"><span>WiFi名2</span><input type=\"text\" name=\"ssid2\" value=\"\"></label><label class=\"input\"><span>WiFi密码2</span><input type=\"text\"  name=\"pass2\"></label><input class=\"btn\" type=\"submit\" name=\"submit\" value=\"上传\"> <p><span> 附近的 wifi: </P></form>"
//定义成功页面HTML源代码
#define SUCCESS_HTML "<html><body><font size=\"10\">successd,wifi connecting...<br />Please close this page manually.</font></body></html>"

DNSServer dnsServer;        //创建dnsServer实例
WebServer server(webPort);  //开启web服务, 创建TCP SERVER,参数: 端口号,最大连接数

bool shouldreboot = false;  // 重启标志，固件升级操作完成后设置该标志准备重启设备
//定义根目录首页网页HTML源代码
const char* ROOTset_HTML0 PROGMEM = R"=====(
<!DOCTYPE html>
<html>

<head>
  <meta charset='UTF-8'>
  <title>WIFI Config by dht</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style type="text/css">
    body {
      display: flex;
      align-items: center;
      justify-content: center;
      flex-direction: column;
      background-color: #f5f5f5;
      margin: 0;
      padding: 0;
      height: 100vh;
      font-family: Arial, sans-serif;
    }

    .nav {
      display: flex;
      justify-content: center;
      position: fixed;
      bottom: 0;
      background-color: #f5f5f5;
      width: 100%;
      padding: 20px 0;
      box-shadow: 0px -2px 10px rgba(0, 0, 0, 0.1);
    }

    .nav-button {
      margin: 0 10px;
      padding: 8px 16px;
      background-color: #ebebeb;
      border: none;
      color: #333;
      font-size: 14px;
      cursor: pointer;
    }

    .nav-button.active {
      background-color: #ccc;
      font-weight: bold;
    }

    .page {
      display: none;
      padding: 20px;
      background-color: #fff;
      border-radius: 8px;
      margin-bottom: 70px;
    }

    body {
      display: flex;
      align-items: center;
      justify-content: center;
      flex-direction: column;
      background-color: #f5f5f5;
    }

    .set {
      text-align: center;
      display: block;
      margin-top: 10px;
      background-color: rgb(130, 175, 241);
    }

    .end {
      text-align: center;
      display: block;
      margin-top: 10px;
      background-color: rgb(164, 201, 255);
    }

    .end span {
      text-align: center;
      width: 150px;
      float: center;
      height: 36px;
      line-height: 36px;
      color: rgb(255, 255, 255);
    }

    .set span {
      text-align: center;
      width: 150px;
      float: center;
      height: 36px;
      line-height: 36px;
      color: rgb(255, 255, 255);
    }

    .input {
      text-align: center;
      display: block;
      margin-top: 10px;
    }

    .input span {
      text-align: center;
      width: 150px;
      float: center;
      height: 36px;
      line-height: 36px;
      color: rgb(130, 175, 241);
    }

    .input input {
      text-align: center;
      height: 30px;
      width: 150px;
    }

    .btn {
      width: 120px;
      height: 35px;
      background-color: rgb(130, 175, 241);
      border: 0px;
      color: white;
      margin-top: 15px;
      margin-left: auto;
      margin-right: auto;
      display: block;
      border-radius: 8px;
      cursor: pointer;
    }

    font {
      color: rgb(130, 175, 241);
      text-align: center;
    }

    input[type="file"] {
      display: block;
      margin: 15px auto;
      padding: .5rem;
      width: 150px;
      height: auto;
      background-color: rgb(130, 175, 241);
      color: rgb(255, 255, 255);
      border-radius: 5px;
      overflow: auto;
      cursor: pointer;
    }

    input[type="submit"] {
      display: block;
      margin: 15px auto;
      padding: 0.5rem;
      width: 100px;
      height: auto;
      background-color: rgb(130, 175, 241);
      color: #fff;
      border-radius: 5px;
      border: none;
      cursor: pointer;
    }

    .copyable-text {
      display: inline-block;
      width: 200px;
      overflow: auto;
      text-overflow: auto;
      white-space: nowrap;
      cursor: pointer;
      user-select: all;
      /* 允许文本被选中复制 */
    }

    .upload {
      display: flex;
      flex-direction: column;
      align-items: center;
    }
    .inputupload {
  display: flex;
}

.text {
  flex: 1;
}
.file {
  flex: 1;
}
.btn {
  flex: 1;
}
  </style>
  <script>
    function switchPage(pageId) {
      var buttons = document.getElementsByClassName("nav-button");
      for (var i = 0; i < buttons.length; i++) {
        buttons[i].classList.remove("active");
      }

      var pages = document.getElementsByClassName("page");
      for (var i = 0; i < pages.length; i++) {
        pages[i].style.display = "none";
      }

      var selectedButton = document.getElementById(pageId + "-button");
      selectedButton.classList.add("active");

      var selectedPage = document.getElementById(pageId);
      selectedPage.style.display = "block";
    }
  </script>
</head>

<body>
  <div id="wifi-page" class="page">
    <h1>配网</h1>
    <form method="POST" action="configwifi">
      <label class="input">
      <span>WiFi名称1</span>
      <input type="text" name="ssid" value="">
    </label>
      <label class="input">
      <span>WiFi密码1</span>
      <input type="text" name="pass">
    </label>
      <label class="input">
      <span>WiFi名称2</span>
      <input type="text" name="ssid2" value="">
    </label>
      <label class="input">
      <span>WiFi密码2</span>
      <input type="text" name="pass2">
    </label>
      <input class="btn" type="submit" name="submit" value="上传">
      <p><span>附近的WiFi：</span></p>
    </form>
  
)=====";




const char* ROOTset_HTML1 PROGMEM = R"=====( </div>
  </div>

  <div id="settings-page" class="page">
    <h1>设置</h1>
    <label class="set"><span>EPA-02 设置</span></label>
    <form method="POST" action="configset">
      <label class="input">
<span>巴法云UID</span>
<input type="text" placeholder="使用图库，备忘录必填项" name="bafaUID" value="">
</label>
      <label class="input">
<span>巴法云TOPIC</span>
<input type="text"placeholder="使用图库，备忘录必填项" name="bafaTOPIC" value="">
</label>
      <label class="input">
<span>默认表盘</span>
<input type="text" placeholder="0传统表盘 1数字 2自定义" name="defaultclock" value="">
</label>
      <label class="input">
<span>心知天气UID</span>
<input type="text" placeholder="使用天气时钟必填项" name="xinzhiUID">
</label>
      <label class="input">
<span>心知天气城市</span>
<input type="text" placeholder="使用天气时钟必填项" name="xinzhiCity" value="">  
<label class="input">
<span>格言来源</span>
<input type="text"placeholder="请填 一言 或 历史" name="quote" value="">  
<input class="btn" type="submit" name="submit" value="上传">
</label><label class="set"><span>EPA-02 OTA升级</span></label>

      <label class="input"><SPAN><a href="http://bin.bemfa.com/b/3BcN2ViMWFjNTk5NDA1NDc0ODlkN2E3NzllMjExMWExNTE=ota.bin">前往下载ota文件 </a></SPAN></label>
    </form>
    <form method='POST' action='/update' enctype='multipart/form-data'>
      <input style="display:block;margin-left:auto;margin-right:auto;margin-top:15px" type='file' name='firmware'>
      <input style="display:block;margin-left:auto;margin-right:auto;margin-top:15px" type='submit' style="color:blue">
    </form>
    <label class="input">
</label>
  </div>

  <div id="end-page" class="page">
    <h1>配置完成</h1>
    <p>WiFi已成功配置。</p>
    <button class="btn" onclick="switchPage('wifi-page')">返回</button>
  </div>
  </div>

  <div class="upload">
    <div id="pic-page" class="page">
      <label class="set"><span>传图</span></label>

      <head>
        <title>HTML 画板</title>
        <style>
          #canvas {
            border: 1px solid black;
          }
        </style>
      </head>

      <body>


        <div class="upload">
          <canvas align-items="center;" id="canvas" width="200" height="200"></canvas>
        </div>
        <div class="inputupload">
          <input type="file" id="upload" accept="image/*">
          <button id="modulate-btn"class="btn">无抖动取模</button>
          <button id="dither-btn"class="btn">抖动算法取模</button>
        </div>

        <label class="input">

    <form method="POST" action="configpic"> 
      <div class="copyable-text" id="result">
    </div> 
<div class="inputupload">    
<input class="upload" type="text"placeholder="请填入上方取模完成的数据" name="picout" value="">  
<input class="upload" type="text"placeholder="图片名 (pic0为熄屏图片)" name="picoutname" value="">  
      <input class="btn" type="submit" name="submit" value="上传 图片">
      </div> 
    </form>
    <form method="POST" action="clockpic"> 
      <div class="inputupload"style="display: flex; justify-content: center;">    
      <input class="upload" type="text"placeholder="请填入上方取模完成的数据" name="clockpic" value=""> 
      <input class="upload" type="text"placeholder="时钟位置 0上 1中 2下" name="clocklocation" value=""> 
  <input class="btn" type="submit" name="submit" value="上传 表盘"></div> 
    </form>

    </label>
        <label class="set"><span>传书(仅txt) | 音频代码</span></label>
        <form action="/uploadbook" method="post" enctype="multipart/form-data">
          <input type="file" name="txtFile"><input type="submit" value="上传">
        </form>
        <form method="POST" action="/uploadmusic"> 
        <div class="inputupload" style="display: flex; justify-content: center;">
          <input class="upload" type="text"placeholder="输入音频代码" name="musiccode" value="">
          <input class="upload" type="text"placeholder="输入音频名称" name="musicname" value=""><input type="submit" value="上传">
        </div></form>

        <label class="set"><span> **</span></label>

    </div>
    <script>
      var copyableTextElement = document.getElementById("result");

      copyableTextElement.addEventListener('click', function() {
        // 通过创建临时文本域将文本复制到剪贴板
        var tempTextArea = document.createElement("textarea");
        tempTextArea.value = copyableTextElement.textContent;
        document.body.appendChild(tempTextArea);
        tempTextArea.select();
        document.execCommand("copy");
        document.body.removeChild(tempTextArea);

        // 弹出复制成功的提示
        alert("文本已复制！");
      });

        var canvas = document.getElementById('canvas');
      var ctx = canvas.getContext('2d');
      var painting = false;
-

      canvas.addEventListener('mousedown', startPainting);
      canvas.addEventListener('mousemove', paint);
      canvas.addEventListener('mouseup', stopPainting);

      function startPainting(event) {
        painting = true;
        draw(event);
      }

      function paint(event) {
        if (!painting) return;
        draw(event);
      }

      function stopPainting() {
        painting = false;
      }

      function draw(event) {
        var x = event.clientX - canvas.offsetLeft;
        var y = event.clientY - canvas.offsetTop;

        ctx.lineWidth = 5;
        ctx.lineCap = 'round';
        ctx.lineTo(x, y);
        ctx.stroke();
        ctx.beginPath();
        ctx.moveTo(x, y);
      }

      var uploadInput = document.getElementById('upload');
      uploadInput.addEventListener('change', handleUpload);

function handleUpload(event) {
  var file = event.target.files[0];
  var reader = new FileReader();

  reader.onload = function(e) {
    var image = new Image();
    image.onload = function() {
      // 计算图片的缩放比例
      var scale = Math.min(canvas.width / image.width, canvas.height / image.height);

      // 计算调整后的图片尺寸
      var newWidth = image.width * scale;
      var newHeight = image.height * scale;

      // 清空画布
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      // 在画布上居中绘制图片
      var x = (canvas.width - newWidth) / 2;
      var y = (canvas.height - newHeight) / 2;
      ctx.drawImage(image, x, y, newWidth, newHeight);
    }
    image.src = e.target.result;
  }
  reader.readAsDataURL(file);
}

      function picsolve() {
        var canvasData = ctx.getImageData(0, 0, canvas.width, canvas.height);
        var pic0 = "";
        var picout0 = "";
        var Y = 0.0;
        var t = 0;
        for (var i = 0; i < canvasData.data.length; i += 4) {
          Y =
            0.299 * canvasData.data[i + 0] +
            0.587 * canvasData.data[i + 1] +
            0.114 * canvasData.data[i + 2];
          if (Y >= 200) {
            pic0 += "1";
          } else {
            pic0 += "0";
          }
        }
        for (var i = 0; i < pic0.length; i += 8) {
          var m = parseInt(pic0.substring(i, i + 8), 2);
          var n = m.toString(16);
          if (n.length < 2) {
            n = "0" + n;
          }
          picout0 += n;
        }
        // 将取模结果显示在屏幕上
        var result = document.getElementById("result");
        result.innerHTML = picout0;
      }

      var modulateBtn = document.getElementById("modulate-btn");
      modulateBtn.addEventListener("click", picsolve);

      // 抖动算法取模
      function saturated_add(val1, val2) {
        var val1_int = val1;
        var val2_int = val2;
        var tmp = val1_int + val2_int;

        if (tmp > 255) {
          return 255;
        } else if (tmp < 0) {
          return 0;
        } else {
          return tmp;
        }
      }

      function dither(img) {
        var err;
        var a, b, c, d;
        for (var y = 0; y < 200; y++) {
          for (var x = 0; x < 200; x++) {
            if (img[x + y * 200] > 127) {
              err = img[x + y * 200] - 255;
              img[x + y * 200] = 255;
            } else {
              err = img[x + y * 200] - 0;
              img[x + y * 200] = 0;
            }

            a = (err * 7) / 16;
            b = (err * 1) / 16;
            c = (err * 5) / 16;
            d = (err * 3) / 16;

              if (y != 200 - 1 && x != 0 && x != 200 - 1) {
              img[x + 1 + y * 200] = saturated_add(img[x + 1 + y * 200], a);
              img[x + 1 + (y + 1) * 200] = saturated_add(
                img[x + 1 + (y + 1) * 200],
                b
              );
              img[x + (y + 1) * 200] = saturated_add(
                img[x + (y + 1) * 200],
                c
              );
              img[x + 1 + (y + 1) * 200] = saturated_add(
                img[x + 1 + (y + 1) * 200],
                d
              );
            }
          }
        }
      }

      function picdither() {
        var canvasData = ctx.getImageData(0, 0, canvas.width, canvas.height);
        var pic = [];
        var pic0 = "";
        var picout0 = "";
        var Y = 0.0;
        var t = 0;
        for (var i = 0; i < canvasData.data.length; i += 4) {
          Y =
            0.299 * canvasData.data[i + 0] +
            0.587 * canvasData.data[i + 1] +
            0.114 * canvasData.data[i + 2];
          pic[t] = Y;
          t++;
        }
        dither(pic);
        for (var i = 0; i < pic.length; i++) {
          if (pic[i] == 255) {
            pic[i] = 1;
          } else {
            pic[i] = 0;
          }
          pic0 += pic[i];
        }
        for (var i = 0; i < pic0.length; i += 8) {
          var m = parseInt(pic0.substring(i, i + 8), 2);
          var n = m.toString(16);
          if (n.length < 2) {
            n = "0" + n;
          }
          picout0 += n;
        }
        // 将取模结果显示在屏幕上
        var result = document.getElementById("result");
        result.innerHTML = picout0;
      }

      var ditherBtn = document.getElementById("dither-btn");
      ditherBtn.addEventListener("click", picdither);
    </script>
</body>
</form>
</div>
<div class="nav">
  <button id="wifi-page-button" class="nav-button active" onclick="switchPage('wifi-page')">
      配网
    </button>
  <button id="settings-page-button" class="nav-button" onclick="switchPage('settings-page')">
      设置
    </button>
  <button id="pic-page-button" class="nav-button active" onclick="switchPage('pic-page')">
      传输
    </button>

</div>

<script>
  // 默认显示开始页面
    switchPage("wifi-page");
</script>
</body>

</html>

 )=====";
//扫描WiFi
bool scanWiFi() {
  Serial.println("scan start");
  // 扫描附近WiFi
  int n = WiFi.scanNetworks();
  n = 4;  //太多了就要4个
  Serial.println("scan done");
  if (n == 0) {
    Serial.println("no networks found");
    scanNetworksID = "no networks found";
    return false;
  } else {
    Serial.print(n);
    Serial.println(" networks found");
    for (int i = 0; i < n; ++i) {
      // Print SSID and RSSI for each network found
      Serial.print(i + 1);
      Serial.print(": ");
      Serial.print(WiFi.SSID(i));
      Serial.print(" (");
      Serial.print(WiFi.RSSI(i));
      Serial.print(")");
      Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*");
      scanNetworksID += "<P>" + WiFi.SSID(i) + "</P>";
      delay(10);
    }
    return true;
  }
}
//定义成功页面HTML源代码
#define SUCCESSset_HTML "<html><body><font size=\"10\">successd<br />Please close this page manually.</font></body></html>"
String _updaterError = "";
void connectToWiFi(int timeOut_s, int mod = 0) {
  display.firstPage();
  display.fillScreen(BackC);
  drawScale(peiwangicon, 68, 48, 64, 64, 1, 1, false);
  centerx("配网中...", 125, 1, 0, 200, "否");
  nextPage(10, -1);
  Serial.println("进入connectToWiFi()函数");
  //设置为STA模式并连接WIFI
  WiFi.mode(WIFI_STA);
  WiFi.setAutoConnect(true);  //设置自动连接
  //用字符串成员函数c_str()生成一个const char*指针，指向以空字符终止的数组,即获取该字符串的指针。
  if (wifi_ssid != "") {
    Serial.println("用web配置信息连接.");

    WiFi.begin(wifi_ssid.c_str(), wifi_pass.c_str());
    wifi_ssid = "";
    wifi_pass = "";

  } else {
    Serial.println("用nvs保存的信息连接.");
    WiFi.begin();  //连接上一次连接成功的wifi
  }

  //WiFi.begin(wifi_ssid.c_str(), wifi_pass.c_str());
  int Connect_time = 0;                    //用于连接计时，如果长时间连接不成功，复位设备
  while (WiFi.status() != WL_CONNECTED) {  //等待WIFI连接成功

    Serial.print(".");
    digitalWrite(lightpin, !digitalRead(lightpin));
    delay(500);
    Connect_time++;
    if (Connect_time > 2 * timeOut_s && mod == 0) {  //长时间连接不上，退出

      digitalWrite(lightpin, LOW);
      Serial.println("");
      Serial.println("WIFI autoconnect fail, start AP for webconfig now...");
      //wifiConfig();  //转到网页端手动配置wifi
      return;  //跳出 防止无限初始化
    } else if (Connect_time > 2 * timeOut_s && mod == 1) {

      return;
    }
  }
  if (WiFi.status() == WL_CONNECTED) {

    Serial.println("WIFI connect Success");

    digitalWrite(lightpin, HIGH);
    server.stop();
  }
  centerx("好了好了!", 125, 1, 0, 200, "否");
  nextPage(10, -1);
  digitalWrite(lightpin, LOW);
  centerx("好了好了!", 145, 1, 0, 200, "否");
  nextPage(10, -1);
}
//初始化AP模式
void initSoftAPset() {
  WiFi.mode(WIFI_AP);                                          //配置为AP模式
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));  //设置AP热点IP和子网掩码
  if (WiFi.softAP(APset_SSID)) {                               //开启AP热点,如需要密码则添加第二个参数
    //打印相关信息
    Serial.println("ESP-32 SoftAP is right.");
    Serial.print("Soft-AP IP address = ");
    Serial.println(WiFi.softAPIP());
    Serial.println(String("MAC address = ") + WiFi.softAPmacAddress().c_str());
  } else {  //开启热点失败
    Serial.println("WiFiAP Failed");
    delay(1000);
    Serial.println("restart now...");
    ESP.restart();  //重启复位esp32
  }
}

//初始化DNS服务器
void initDNSset() {
  //判断将所有地址映射到esp32的ip上是否成功
  if (dnsServer.start(DNS_PORT, "*", apIP)) {
    Serial.println("start dnsserver success.");
  } else {
    Serial.println("start dnsserver failed.");
  }
}
void handleResponse()  //回调函数
{
  server.sendHeader("Connection", "close");
  //if (Update.hasError()) {
  //  server.send(200, F("text/html"), String(F("Update error:")) + _updaterError);
  //}
  server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
}

void handleFileupload()  //回调函数
{
  HTTPUpload& upload = server.upload();    // 文件上传对象
  if (upload.status == UPLOAD_FILE_START)  // 文件上传开始
  {
    Serial.printf("开始上传文件: %s\n", upload.filename.c_str());
    if (!Update.begin())  // 开始固件升级，检查空可用间大小，如果正在升级或空间不够则返回false
    {
      Update.printError(Serial);
    }
  } else if (upload.status == UPLOAD_FILE_WRITE)  // 文件读写中
  {
    if (Update.write(upload.buf, upload.currentSize) != upload.currentSize)  // 将文件数据写入到OTA区域
    {
      Update.printError(Serial);
    }
  } else if (upload.status == UPLOAD_FILE_END)  // 文件上传完成
  {
    Serial.println("写入" + String(upload.totalSize) + "字节到OTA区域");
    if (!Update.end(true))  // 完成数据写入，设置在系统重启后自动将OTA区域固件移动到Sketch区域 // Update.begin不指定大小时这里设置true
    {
      Update.printError(Serial);
    }
    Serial.println("升级操作完成，模块将在1秒后重启以完成固件升级");
    shouldreboot = true;
  } else {
    Serial.printf("固件上传失败: status=%d\n", upload.status);
  }
}
void handleConfigWifi() {
  //返回http状态
  //server.send(200, "text/html", SUCCESS_HTML);
  if (server.hasArg("ssid")) {  //判断是否有账号参数
    Serial.print("got ssid:");
    wifi_ssid = server.arg("ssid");    //获取html表单输入框name名为"ssid"的内容
    wifi_ssid2 = server.arg("ssid2");  //获取html表单输入框name名为"ssid"的内容
    EEPROM.writeString(1000, wifi_ssid);
    EEPROM.writeString(1100, wifi_ssid2);
    // strcpy(sta_ssid, server.arg("ssid").c_str());//将账号参数拷贝到sta_ssid中
    Serial.println(wifi_ssid);
  } else {  //没有参数
    Serial.println("error, not found ssid");
    server.send(200, "text/html", "<meta charset='UTF-8'>error, not found ssid");  //返回错误页面
    return;
  }
  //密码与账号同理
  if (server.hasArg("pass")) {
    Serial.print("got password:");
    wifi_pass = server.arg("pass");    //获取html表单输入框name名为"pwd"的内容
    wifi_pass2 = server.arg("pass2");  //获取html表单输入框name名为"pwd"的内容
    EEPROM.writeString(1050, wifi_pass);
    EEPROM.writeString(1150, wifi_pass2);
    //strcpy(sta_pass, server.arg("pass").c_str());
    Serial.println(wifi_pass);
  } else {
    Serial.println("error, not found password");
    server.send(200, "text/html", "<meta charset='UTF-8'>error, not found password");
    return;
  }
  EEPROM.commit();
  server.send(200, "text/html", "<meta charset='UTF-8'>SSID：" + wifi_ssid + "<br />password:" + wifi_pass + "<br />已取得WiFi信息,正在尝试连接,请手动关闭此页面。");  //返回保存成功页面
  delay(2000);
  WiFi.softAPdisconnect(true);  //参数设置为true，设备将直接关闭接入点模式，即关闭设备所建立的WiFi网络。
  server.close();               //关闭web服务
  WiFi.softAPdisconnect();      //在不输入参数的情况下调用该函数,将关闭接入点模式,并将当前配置的AP热点网络名和密码设置为空值.
  Serial.println("WiFi Connect SSID:" + wifi_ssid + "  PASS:" + wifi_pass);
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("开始调用连接函数connectToWiFi()..");
    connectToWiFi(connectTimeOut_s);  //进入配网阶段
  } else {
    Serial.println("提交的配置信息自动连接成功..");
  }
}




//删除保存的wifi信息,并使LED闪烁5次
void restoreWiFi() {
  esp_wifi_restore();  //删除保存的wifi信息
  Serial.println("连接信息已清空,准备重启设备..");
}

void checkConnect(bool reConnect) {
  if (WiFi.status() != WL_CONNECTED) {
    //  Serial.println("WIFI未连接.");
    //  Serial.println(WiFi.status());
    if (reConnect == true && WiFi.getMode() != WIFI_AP && WiFi.getMode() != WIFI_AP_STA) {
      Serial.println("WIFI未连接.");
      Serial.println("WiFi Mode:");
      Serial.println(WiFi.getMode());
      Serial.println("正在连接WiFi...");
      connectToWiFi(connectTimeOut_s);
    }
  }
}
//处理网站根目录“/”(首页)的访问请求,将显示配置wifi的HTML页面
void handleConfigpic() {
  if (server.hasArg("picout") && server.arg("picout").length() > 0&&server.hasArg("picoutname") && server.arg("picoutname").length() > 0) {  //判断是否有账号参数
    Serial.print("got picout:");
    picout = server.arg("picout");  //获取html表单输入框name名为"picout"的内容
    Serial.println(picout);
String picoutname=server.arg("picoutname");
    FFat.remove(picoutname.c_str());
    File file = FFat.open(("/[p]"+picoutname+".p").c_str(), "w");
    if (file) {
      Serial.println("写入");
      file.print(picout);
    }
    file.close();
    server.send(200, "text/plain", "ok");


  } else {
    server.send(200, "text/plain", "FAIL");
    Serial.println("不行");
  }
}
extern int clocklocation;
void clockpic() {
  if (server.hasArg("clockpic") && server.arg("clockpic").length() > 0) {  //判断是否有账号参数
    if (server.hasArg("clocklocation")) {
      clocklocation = atoi((server.arg("clocklocation")).c_str());
      EEPROM.write(111, clocklocation);
      EEPROM.commit();
    }
    Serial.print("got picout:");
    picout = server.arg("clockpic");  //获取html表单输入框name名为"picout"的内容
    Serial.println(picout);
    FFat.remove("/[p]clockpic.p");
    File file = FFat.open("/[p]clockpic.p", "w");
    if (file) {
      Serial.println("写入");
    }
    file.print(picout);
    file.close();
    server.send(200, "text/plain", "ok");


  } else {
    server.send(200, "text/plain", "FAIL");
    Serial.println("不行");
  }
}
void handlemusic(){
  if (server.hasArg("musiccode") && server.arg("musiccode").length() > 0&&server.hasArg("musicname") && server.arg("musicname").length() > 0) {  //判断是否有账号参数
    Serial.print("got music:");
   String musiccode = server.arg("musiccode");  //获取html表单输入框name名为"picout"的内容
    Serial.println(musiccode);
String musicname=server.arg("musicname");
    FFat.remove(musicname.c_str());
    File file = FFat.open(("/[m]"+musicname+".m").c_str(), "w");
    if (file) {
      Serial.println("写入");
      file.print(musiccode);
    }
    file.close();
    server.send(200, "text/plain", "ok");


  } else {
    server.send(200, "text/plain", "FAIL");
    Serial.println("不行");
  }
}
void handleuploadbook() {
  // 检查是否有文件上传
  Serial.println("aaaaaaaa");
  //if (server.hasArg("txtFile")) {

  HTTPUpload& uploadbook = server.upload();

  // 检查是否是新上传的文件
  if (uploadbook.status == UPLOAD_FILE_START) {
    // 打开文件
    Serial.println("start");
    fs::File f = FFat.open("/" + uploadbook.filename, FILE_WRITE);
    if (!f) {
      Serial.println("Failed to open file for writing");
      server.send(500, "text/plain", "Failed to open file for writing");
      return;
    }
    f.close();
  } else if (uploadbook.status == UPLOAD_FILE_WRITE) {
    // 打开文件
    fs::File f = FFat.open("/" + uploadbook.filename, FILE_APPEND);
    if (!f) {
      Serial.println("Failed to open file for writing");
      server.send(500, "text/plain", "Failed to open file for writing");
      return;
    }

    // 写入文件内容
    size_t bytesWritten = f.write(uploadbook.buf, uploadbook.currentSize);
    if (bytesWritten != uploadbook.currentSize) {
      Serial.println("File upload failed");
      server.send(500, "text/plain", "File upload failed");
    }
    Serial.println("write");
    f.close();
  } else if (uploadbook.status == UPLOAD_FILE_END) {
    Serial.println("File upload successful");
    server.send(200, "text/plain", "File upload successful");
    return;
    // File file = FFat.open("/"+uploadbook.filename);
    // Serial.println("- read from file:");
    // while (file.available()) {
    //   Serial.write(file.read());
    // }
    // file.close();
  }
  //}
}


void handleRootset() {
  // if (server.hasArg("selectSSID")) {
  //   server.send(200, "text/html", ROOT_HTML + scanNetworksID + "</body></html>");
  // } else {
  //   server.send(200, "text/html", ROOT_HTML + scanNetworksID + "</body></html>");
  // }
  if (server.hasArg("selectSSID")) {
    server.send(200, "text/html", ROOTset_HTML0 + scanNetworksID + ROOTset_HTML1 + "</body></html>");
  } else {
    server.send(200, "text/html", ROOTset_HTML0 + scanNetworksID + ROOTset_HTML1 + "</body></html>");
  }
}
//提交数据后，返回给客户端信息函数
void handleSetting() {
  bool commit = false;
  bool hiku = false;
  bool history = false;
  //返回http状态
  //server.send(200, "text/html", SUCCESS_HTML);
  if (server.hasArg("bafaUID") && server.arg("bafaUID").length() > 0) {  //判断是否有账号参数
    Serial.print("got bafaUID:");
    bafaUID = server.arg("bafaUID");  //获取html表单输入框name名为"bafaUID"的内容
    EEPROM.writeString(100, bafaUID);
    Serial.println(bafaUID);
    commit = true;
  }
  /*else {  //没有参数
    Serial.println("error, not found bafaUID");
    server.send(200, "text/html", "<meta charset='UTF-8'>error, not found bafaUID");  //返回错误页面
    return;
  }*/
  //密码与账号同理
  if (server.hasArg("xinzhiUID") && server.arg("xinzhiUID").length() > 0) {
    Serial.print("got xinzhiUID:");
    xinzhiUID = server.arg("xinzhiUID");  //获取html表单输入框name名为"xinzhiUID"的内容
    EEPROM.writeString(200, xinzhiUID);
    Serial.println(xinzhiUID);
    commit = true;
  }
  if (server.hasArg("xinzhiCity") && server.arg("xinzhiCity").length() > 0) {  //判断是否有账号参数
    Serial.print("got xinzhiCity:");
    xinzhiCity = server.arg("xinzhiCity");  //获取html表单输入框name名为"xinzhiCity"的内容
    EEPROM.writeString(300, xinzhiCity);
    Serial.println(xinzhiCity);
    commit = true;
  }
  if (server.hasArg("bafaTOPIC") && server.arg("bafaTOPIC").length() > 0) {  //判断是否有账号参数
    Serial.print("got bafaTOPIC:");
    bafaTOPIC = server.arg("bafaTOPIC");  //获取html表单输入框name名为"bafaTOPIC"的内容
    EEPROM.writeString(400, bafaTOPIC);
    Serial.println(bafaTOPIC);
    commit = true;
  }
  if (server.hasArg("defaultclock") && server.arg("defaultclock").length() > 0) {  //判断是否有账号参数
    Serial.print("got defaultclock:");
    defaultclock = atoi(server.arg("defaultclock").c_str());  //获取html表单输入框name名为"defaultclock"的内容
    if (defaultclock == 0 || defaultclock == 1||defaultclock ==2) {
      EEPROM.write(500, defaultclock);
      Serial.println(defaultclock);
      commit = true;
    }
  }
  if (server.hasArg("quote") && server.arg("quote").length() > 0) {  //判断是否有账号参数
    Quotemod = server.arg("quote");
    if (Quotemod == "一言") {
      EEPROM.writeString(980, "0");
      delay(200);
      EEPROM.commit();

    } else if (Quotemod == "历史") {
      EEPROM.writeString(980, "1");
      delay(200);
      EEPROM.commit();
    }
    commit = true;
  }

  if (commit == true) {
    EEPROM.commit();
    server.send(200, "text/html", "<meta charset='UTF-8'>巴法云UID：" + bafaUID + "<br />巴法云TOPIC:" + bafaTOPIC + "<br />巴法云昵称:" + bafaNAME + "<br />心知UID:" + xinzhiUID + "<br />心知城市:" + xinzhiCity + "<br />已取得信息,请手动关闭此页面。");  //返回保存成功页面
    delay(200);
    WiFi.softAPdisconnect(true);  //参数设置为true，设备将直接关闭接入点模式，即关闭设备所建立的WiFi网络。
    server.close();               //关闭web服务
    WiFi.softAPdisconnect();      //在不输入参数的情况下调用该函数,将关闭接入点模式,并将当前配置的AP热点网络名和密码设置为空值.
    //PeiWangStart();
  }
}

// 设置处理404情况的函数'handleNotFoundset'
void handleNotFoundset() {  // 当浏览器请求的网络资源无法在服务器找到时通过此自定义函数处理
  handleRootset();          //访问不存在目录则返回配置页面
  //   server.send(404, "text/plain", "404: Not found");
}

//初始化WebServer
void initWebServerset() {
  //给设备设定域名esp32,完整的域名是esp32.local
  if (MDNS.begin("esp32")) {
    Serial.println("MDNS responder started");
  }
  //必须添加第二个参数HTTP_GET，以下面这种格式去写，否则无法强制门户
  server.on("/", HTTP_GET, handleRootset);            //  当浏览器请求服务器根目录(网站首页)时调用自定义函数handleRootset处理，设置主页回调函数，必须添加第二个参数HTTP_GET，否则无法强制门户
  server.on("/configset", HTTP_POST, handleSetting);  //  当浏览器请求服务器/configset(表单字段)目录时调用自定义函数handleSetting处理
  server.on("/update", HTTP_POST, handleResponse, handleFileupload);
  server.on("/configwifi", HTTP_POST, handleConfigWifi);
  server.on("/configpic", HTTP_POST, handleConfigpic);
server.on("/uploadmusic", HTTP_POST, handlemusic);
  server.on("/clockpic", HTTP_POST, clockpic);
  server.on("/uploadbook", HTTP_POST, handleResponse, handleuploadbook);
  server.onNotFound(handleNotFoundset);  //当浏览器请求的网络资源无法在服务器找到时调用自定义函数handleNotFound处理
  //Tells the server to begin listening for incoming connections.Returns None
  server.begin();  //启动TCP SERVER
                   //server.setNoDelay(true);                                  //关闭延时发送
  Serial.println("WebServer started!");
}
void setConfig() {
  initSoftAPset();
  initDNSset();
  initWebServerset();
  scanWiFi();
}

void Setting() {
  Serial.begin(baudRate);
  WiFi.hostname(HOST_NAME);  //设置设备名
  setConfig();
  do {
    dnsServer.processNextRequest();  //检查客户端DNS请求
    server.handleClient();           //检查客户端(浏览器)http请求
    if (shouldreboot) {
      delay(1000);
      ESP.restart();  // 重启设备
    }
    if (tapcheck(2)) {
      WiFi.softAPdisconnect(true);  //参数设置为true，设备将直接关闭接入点模式，即关闭设备所建立的WiFi网络。
      server.close();               //关闭web服务
      WiFi.softAPdisconnect();
      break;
    }
  } while (1);
}
extern void configtimedesk();
void settingdesk() {//（设置）主界面
  int setselect = 0;
  display.firstPage();
  display.fillScreen(BackC);
  while (1) {
    display.firstPage();
    display.fillScreen(BackC);
    display.drawInvertedBitmap(xshifting, yshifting, settingback, 200, 200, FormC);
    if (setselect != 0) {
      display.drawRoundRect(90 + xshifting, 50 + yshifting + setselect * 47, 20, 3, 1, FormC);
      display.drawRoundRect(90 + xshifting, 50 + yshifting + (setselect - 1) * 47, 20, 3, 1, BackC);
    } else {
      display.drawRoundRect(90 + xshifting, 50 + yshifting + setselect * 47, 20, 3, 1, FormC);
      display.drawRoundRect(90 + xshifting, 50 + yshifting + 3 * 47, 20, 3, 1, BackC);
    }
    nextPage(10, -1);
    espsleep(1);
    if (tapcheck(1)) setselect = (setselect == 3) ? 0 : setselect + 1;
    if (tapcheck(2)) {
      switch (setselect) {
        case 0:
          configtimedesk();
          break;
        case 1:
          connectToWiFi(5, 1);
          nextPage(10, -1);
          break;
        case 2: SettingStart(); break;
        case 3: return;
      }
    }
  }
  nextPage(10, -1);
}

void SettingStart() {//网页端的设置启动
  display.firstPage();
  display.fillScreen(BackC);
  drawScale(settingicon, 68, 48, 64, 64, 1, 1, false);
  centerx("设置中...", 125, 1, 0, 200, "否");
  centerx("请连接热点：ESP32SET配置", 145, 1, 0, 200, "否");
  nextPage(10, 0);
  Setting();
  centerx("设置完成", 125, 1, 0, 200, "否");
  nextPage(10, 0);
}